Skip to content

Conversation

@cachebag
Copy link
Contributor

@cachebag cachebag commented Jan 6, 2026

This PR employs symlink preservation in copy_file and adds it to copy_dir.

PR #1504 added symlink preservation to fix crashes in lldb-preview, which contains internal symlinks (liblldb was loading twice due to broken symlinks). Then, PR #1521 later changed copy_file to create symlinks pointing to the source path (for Homebrew integration), which may have regressed #1504.

This PR restores #1504's behavior: read the symlink target and preserve it. What I'm curious about is what the intended behavior for #1521 was because shouldn't users be able to run rustup-init --no-self-update? Is that not the recommended way to manage rustup via external package managers?

If this PR steers out of scope of the goals of rustup I'm happy to close it but I feel like the former behavior is preferable for most use cases.

Previously, copy_dir would follow symlinks and copy the target
contents. Now it preserves symlinks by reading the link target
and creating a new symlink with the same target.

Adds regression test copy_dir_preserves_symlinks.
Previously, copy_file created a symlink pointing to the source
path rather than preserving the original symlink's target.
Now it reads the link target and creates a symlink with that
same target.

Adds regression test copy_file_preserves_symlinks.
@rami3l rami3l self-assigned this Jan 8, 2026
@rami3l
Copy link
Member

rami3l commented Jan 14, 2026

Thanks for making this patch! Reasonable support for external packagers are still expected, and whether a manual setup is required is largely based on the packagers' opinion: https://rust-lang.github.io/rustup/installation/other.html#using-a-package-manager

I have the feeling that we need to somehow support both cases based on whether that's copying the original binary or not...

Copy link
Member

@rami3l rami3l left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a specific use case where rustup is not working as you'd expect, which this PR allows to fix?

If you can find such a case, I agree with using this new implementating except for this:

utils::copy_file(&this_exe_path, &rustup_path)?;

#1521 is probably too widespread as a fix, and it makes perfect sense to use different copy implementations during self installation and during toolchain installation.

Suggest refining the test cases accordingly if going this way.

let dest = dest.join(entry.file_name());
if kind.is_dir() {
copy_dir(&src, &dest)?;
let src_path = entry.path();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: src and dest bindings in the loop body are preventing the input params from being used. Thus, I don't see a very convincing reason to rename them here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants